Problem
Dynamic len(set(a[L:R]))
Description
In python, we can use len(start(a[L:R])) to calculate the number of distinct values of elements a [ L ] , a [ L + 1 ] , ⋯ , a [ R − 1 ] a[L],a[L + 1], \cdots,a[R-1] a [ L ] , a [ L + 1 ] , ⋯ , a [ R − 1 ] .
Tere are some interactive examples that may help you understand how it is done. Remember that the indices of python lists start from 0 0 0 .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 >>> a=[1,2,1,3,2,1,4] >>> print a[1:6] [2, 1, 3, 2, 1] >>> print set(a[1:6]) set([1, 2, 3]) >>> print len(set(a[1:6])) 3 >>> a[3]=2 >>> print len(set(a[1:6])) 2 >>> print len(set(a[3:5])) 1
Your task is to simulate this process.
There will be only one test case. The first line contains two integers n n n and m m m ( 1 ≤ n , m ≤ 50 , 000 ) (1\le n,m\le 50,000) ( 1 ≤ n , m ≤ 5 0 , 0 0 0 ) .
The next line contains the original list.
All the integers are between 1 1 1 and 1 , 000 , 000 1,000,000 1 , 0 0 0 , 0 0 0 (inclusive). The next m lines contain the statements
that you need to execute.
A line formatted as ‘M M M x x x y y y ’ ( 1 ≤ y ≤ 1 , 000 , 000 ) (1\le y\le 1,000,000) ( 1 ≤ y ≤ 1 , 0 0 0 , 0 0 0 ) means a [ x ] = y a[x] = y a [ x ] = y , and a line formatted as ‘Q Q Q x x x
y y y ’ means p r i n t l e n ( s e t ( a [ x : y ] ) ) print\ len(set(a[x : y])) p r i n t l e n ( s e t ( a [ x : y ] ) ) .
It is guaranteed that the statements will not cause i n d e x index i n d e x o u t out o u t o f of o f r a n g e range r a n g e error.
Output
Print the simulated result, one line for each query.
1 2 3 4 5 6 7 4 1 2 1 3 2 1 4 Q 1 6 M 3 2 Q 1 6 Q 3 5
Sample Output
标签:带修莫队
Translation
给出一个长为n n n 的序列,有m m m 个操作,分为两类:
Q Q Q a a a b b b 询问此序列a ∼ b a\sim b a ∼ b 位间有多少种不同数
M M M a a a b b b 将第a a a 位改为b b b 。
Solution
本题数据范围只有五万,一看就是带根号的算法,可以O ( n n ) O(n\sqrt{n}) O ( n n ) 莫队水过。
我们发现Q Q Q 操作是标准莫队,但M M M 操作是修改,因而需用带修莫队。
带修莫队即在普通莫队的双指针种再加一个指针,指向时间。对于离线后询问建的扩展,如果是同一时间,就直接移动双指针;如果是不同时间,就先暴力移动时间指针,然后再移双指针即可。
暴力出奇迹~~~
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #define MAX_N 50000 #define MAX_C 1000000 using namespace std;int n, m, tmp, col[MAX_N+5 ];int cnt[MAX_C+5 ], pos[MAX_N+5 ], lst[MAX_N+5 ], ans[MAX_N+5 ];bool mark[MAX_N+5 ];struct Modify {int pos, x, pre;} M[MAX_N+5 ];struct Query {int l, r, id, ts;} Q[MAX_N+5 ];bool cmp (const Query &a, const Query &b) { return pos[a.l] < pos[b.l] || (pos[a.l] == pos[b.l] && pos[a.r] < pos[b.r]) || (pos[a.l] == pos[b.l] && pos[a.r] == pos[b.r] && a.ts < b.ts); } void add (int x) { if (mark[x]) { cnt[col[x]]--; if (!cnt[col[x]]) tmp--; } else { if (!cnt[col[x]]) tmp++; cnt[col[x]]++; } mark[x] ^= 1 ; } void change (int x, int y) { if (mark[x]) add (x), col[x] = y, add (x); else col[x] = y; } int main () { scanf ("%d%d" , &n, &m); int magic = (int )(sqrt ((double )n+0.5 )); int tot = 0 , ind = 0 ; for (int i = 1 ; i <= n; i++) scanf ("%d" , &col[i]), lst[i] = col[i], pos[i] = i/magic; for (int i = 1 ; i <= m; i++) { char opt[2 ]; int x, y; scanf ("%s%d%d" , opt, &x, &y); x++; if (opt[0 ] == 'Q' ) { Q[++tot].id = tot; Q[tot].l = x, Q[tot].r = y, Q[tot].ts = ind; } else { M[++ind].pos = x, M[ind].x = y, M[ind].pre = lst[x]; lst[x] = y; } } sort (Q+1 , Q+tot+1 , cmp); int now = 0 , l = 1 , r = 0 ; for (int i = 1 ; i <= tot; i++) { if (now < Q[i].ts) for (int j = now+1 ; j <= Q[i].ts; j++) change (M[j].pos, M[j].x); if (now > Q[i].ts) for (int j = now; j > Q[i].ts; j--) change (M[j].pos, M[j].pre); if (l > Q[i].l) for (int j = l-1 ; j >= Q[i].l; j--) add (j); if (r < Q[i].r) for (int j = r+1 ; j <= Q[i].r; j++) add (j); if (l < Q[i].l) for (int j = l; j < Q[i].l; j++) add (j); if (r > Q[i].r) for (int j = r; j > Q[i].r; j--) add (j); now = Q[i].ts, l = Q[i].l, r = Q[i].r; ans[Q[i].id] = tmp; } for (int i = 1 ; i <= tot; i++) printf ("%d\n" , ans[i]); return 0 ; }